package com.eric.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @description： 文件上传controller
 * @Author: liuBing
 * @DateTime: 2021/12/10 14:37
 */
@RestController
@Api("file")
@RequestMapping("file")
@Slf4j
public class FileController {

    @Autowired
    private HttpServletRequest request;

    /**
     * 文件上传
     * <p>
     * 参考博客
     * https://blog.csdn.net/Xidian2850/article/details/105909335
     *
     * @param file 文件
     * @return 上传结果
     * @throws IOException io异常
     */
    @ApiOperation("上传文件")
    @PostMapping("upload")
    public String upload(MultipartFile file) throws IOException {

        log.info("-------------------- content type :{} ", request.getContentType());

        // MultipartFile file = param.getFile();

        // 文件名 + 扩展名
        log.info("-------------------- original file name : {}", file.getOriginalFilename());

        // 文件路径
        String filePath = "D:\\test\\fileTest\\" + System.currentTimeMillis() + "\\" + file.getOriginalFilename();

        File fileNew = new File(filePath);

        if (!fileNew.isDirectory() && !fileNew.mkdirs()) {
            return "error";
        }

        file.transferTo(fileNew);

        // 获取文件大小
        getFileSize();

        return "success";
    }

    /**
     * 获取文件大小
     */
    public void getFileSize() throws IOException {
        String filePath = "";

        File file = new File(filePath);

        System.out.println(file.length());

        // available 返回 int ，最大 21亿
        FileInputStream fileInputStream = new FileInputStream(file);
        System.out.println(fileInputStream.available());
    }


    public static final String FILE_PATH = "/Users/liubing/Documents/";
    public static final String FILE_NAME = "SystemDocumentation.pdf";

    @ApiOperation("系统说明文档更新接口")
    @PostMapping("/system-documentation/upload")
    @SneakyThrows
    public void uploadFileTest(@RequestParam("file") MultipartFile file) {
        File newF = new File(FILE_PATH + FILE_NAME);
        if (!newF.getParentFile().exists()) {
            boolean a = newF.getParentFile().mkdirs();
            System.out.println(a);
        }
        file.transferTo(newF);
    }

    private static final String UPLOAD_DIR = "uploads/";


    @PostMapping("/upload")
    public String uploadFile(
            @RequestParam("file") MultipartFile file,
            @RequestParam("chunkIndex") int chunkIndex,
            @RequestParam("totalChunks") int totalChunks) {
        try {
            // Create upload directory if it doesn't exist
            File uploadDir = new File(UPLOAD_DIR);
            if (!uploadDir.exists()) {
                uploadDir.mkdirs();
            }

            // Save the chunk to the server
            File chunkFile = new File(UPLOAD_DIR + file.getOriginalFilename() + ".part" + chunkIndex);
            try (InputStream inputStream = file.getInputStream();
                 FileOutputStream outputStream = new FileOutputStream(chunkFile)) {
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
            }

            // Check if all chunks are uploaded and merge them
            if (chunkIndex == totalChunks - 1) {
                File mergedFile = new File(UPLOAD_DIR + file.getOriginalFilename());
                try (FileOutputStream outputStream = new FileOutputStream(mergedFile)) {
                    for (int i = 0; i < totalChunks; i++) {
                        File partFile = new File(UPLOAD_DIR + file.getOriginalFilename() + ".part" + i);
                        try (FileInputStream inputStream = new FileInputStream(partFile)) {
                            byte[] buffer = new byte[1024];
                            int bytesRead;
                            while ((bytesRead = inputStream.read(buffer)) != -1) {
                                outputStream.write(buffer, 0, bytesRead);
                            }
                        }
                        partFile.delete(); // Delete the chunk file after merging
                    }
                }
            }
            return "Chunk " + chunkIndex + " uploaded successfully.";
        } catch (IOException e) {
            e.printStackTrace();
            return "File upload failed: " + e.getMessage();
        }
    }



    private final ExecutorService executor = Executors.newFixedThreadPool(5); // Create a thread pool

    @PostMapping("/upload")
    public String uploadFile(
            @RequestParam("file") MultipartFile file,
            @RequestParam("chunkIndex") int chunkIndex,
            @RequestParam("totalChunks") int totalChunks,
            @RequestParam("fileName") String fileName) {

        // Create upload directory if it doesn't exist
        File uploadDir = new File(UPLOAD_DIR);
        if (!uploadDir.exists()) {
            uploadDir.mkdirs();
        }

        // Save the chunk to the server
        File chunkFile = new File(UPLOAD_DIR + fileName + ".part" + chunkIndex);
        try (InputStream inputStream = file.getInputStream();
             FileOutputStream outputStream = new FileOutputStream(chunkFile)) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "File upload failed: " + e.getMessage();
        }

        // Check if all chunks are uploaded and merge them
        if (chunkIndex == totalChunks - 1) {
            mergeFile(fileName, totalChunks);
        }

        return "Chunk " + chunkIndex + " uploaded successfully.";
    }

    private void mergeFile(String fileName, int totalChunks) {
        executor.submit(() -> {
            File mergedFile = new File(UPLOAD_DIR + fileName);
            try (FileOutputStream outputStream = new FileOutputStream(mergedFile, true)) {
                for (int i = 0; i < totalChunks; i++) {
                    File partFile = new File(UPLOAD_DIR + fileName + ".part" + i);
                    try (FileInputStream inputStream = new FileInputStream(partFile)) {
                        byte[] buffer = new byte[1024];
                        int bytesRead;
                        while ((bytesRead = inputStream.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, bytesRead);
                        }
                    }
                    partFile.delete(); // Delete the chunk file after merging
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }


}
